home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 10 - 1994 / 10.11 Nov 94 / Jasik tip < prev    next >
Encoding:
Text File  |  1994-10-12  |  2.1 KB  |  48 lines  |  [TEXT/R*ch]

  1. Trapping Non-Trap Vector Calls The Debugger has certain limitations in its
  2. ability to trace A-Line traps and such.  As an example, suppose we’re interested
  3. in breaking on calls to CacheFlush.  It’s a trap vector  which is usually
  4. referenced by a JSR ([xx]) instead of the usual A-Line Trap vector.  Because it
  5. doesn’t go through the normal A-line dispatcher, we can’t break on references to
  6. it with the Trap Intercept mechanism. Here’s some example code that creates a
  7. dummy procedure in an application, and an initialization proc that patches the
  8. low-memory trap vector so that it points to the dummy procedure.  I modify the
  9. dummy procedure to make it a JMP to the original value of the low memory vector
  10. [Remember, this is for debugging, not for shipping code.  Shipping code should
  11. generally not modify code it’s about to execute – Ed stb].  Finally, the doPatch
  12. proc undoes the patch and restores the system to its previous state. To use this,
  13. set a breakpoint at my_doPatch_Proc.  When you drop into your debugger, look at
  14. the stack to see who’s calling.  After some looking, you can automate the process
  15. by observing where the interesting return addresses are on the stack with an
  16. action clause (such as the one shown here) that would list them in the -Notes-
  17. window: ?ra := (ra7)^;  { return addr is contents of A7 }
  18.  
  19. { In the next line we check PC for an address in the Quadra 900 ROM } 
  20. if ?pc = 40887824 then ?ra := (ra7+#46+#28)^-2;  { # = decimal } writeln(?ra:ProcPtr);  { display the address as a proc name + offset } 
  21. resume;
  22.  
  23. procedure my_doPatch_Proc; { make it at least 6 bytes long } 
  24. begin 
  25. end;
  26.  
  27. procedure doPatch(doit:Boolean); 
  28. CONST jCacheFlush = $6f4; 
  29. type  jmpL = record opc:integer; addr:Longint; end; 
  30. VAR 
  31.     q:^jmpL; 
  32.     p:^Longint; 
  33. begin
  34.     p := pointer(jCacheFlush);    {$06F4 is the low-mem global jCacheFlush}
  35.     q := @my_doPatch_Proc;
  36.     if doit then begin
  37.                 with q^ do begin 
  38.                         opc := $4EF9; {JMP.L} 
  39.                         addr := p^;  
  40.                 end;
  41.                p^ := Ord(q);
  42.          end
  43.                else begin
  44.                 p^ := q^.addr;  { undo patch }
  45.                end; 
  46. end;
  47. – Steve Jasik, Menlo Park, CA
  48.